Skip to main content

User-Specific G-Code Functions

The CNC11_CustomFunctions.project sample project is located in the installation directory of CODESYS under ..\CODESYS SoftMotion\Examples.

This example shows how to create your own functions for use in expressions in G-code.

For more information about expressions and functions in G-code, see: Expressions. There you will find a list of all operators and functions supported by default.

The example defines the SEL operator from IEC 61131-3 so that it can also be used in G-code.

Structure of the application

As usual for CNC applications, the application consists of path processing (CNC_PreparePath program) and interpolation (CNC program). Because the interpolation does not differ from the other examples, the topic will not be discussed further here.

Path processing is called cyclically every 20 ms in the low-priority PathTask. The interpolation is called cyclically every 4 ms in the high-priority MotionTask. The background task VISU_TASK is defined for the visualization.

In the visualization, you can start processing the G-code and set the value of the variable $LONGLINE$. The G-code and the movement of the machine (3D gantry) are displayed on the right side of the visualization.

The G-code

CNC

LET #WIDTH : LREAL
N10 G36 O#WIDTH D SEL($LONGLINE$, 40, 110)
N20 F50 E100 E-100
N30 G01 X#WIDTH Y#WIDTH Z#WIDTH/2
N40 Y-#WIDTH
N50 X-#WIDTH Z-#WIDTH/2
N60 Y#WIDTH
N70 X0 Y0 Z0

Line 1: Declaration of the local variable #WIDTH of type LREAL.

Line 2, Block N10: Assignment of the value of SEL($LONGLINE$, 40, 110) to the variable #WIDTH. If the value of the PLC variable $LONGLINE$ is TRUE, then the value of the expression is 110; otherwise it is 40.

In the following lines, a rectangle with additional movement in the Z-direction is traversed; the length of one side of the rectangle is 2*#WIDTH.

Implementation of the SEL function

_sm_img_function_sel.png

To create a user-defined function, you need to write a function block which implements the SMC_NC_IFunction interface.

For more information, see: SMC_NC_IFunction.

. The interface defines two methods:
  1. GetSignature. The return type, the count, and the types of the arguments of the function are returned here. In this example, the SEL function returns a value of type T_OTHER and has 3 arguments of type T_BOOL, T_OTHER, and T_OTHER. T_OTHER stands for any type (either T_BOOL, T_LREAL, or T_STRING]. All 3 occurrences of T_OTHER must have the same type.

    METHOD GetSignature
    VAR_OUTPUT
        resultType : SMC_GVar_Type;
        nNumArguments : UDINT;
        pType : POINTER TO SMC_GVar_Type;
    END_VAR
    VAR    argTypes : ARRAY[0..2] OF SMC_GVar_Type :=
            [SMC_GVar_Type.T_BOOL,
             SMC_GVar_Type.T_OTHER,
             SMC_GVar_Type.T_OTHER];
    END_VAR
    
    resultType := SMC_GVAR_Type.T_OTHER;
    nNumArguments := 3;
    pType := ADR(argTypes);
  2. Call: This method is called when the G-code is being processed. The arguments are passed via the pa input. The expression pa[0].argValue.bValue is used to access the Boolean value of the first argument. Depending on the type of the second argument pa[1].argType, the result is the return value result.argType and the branching into a CASE statement.

    METHOD Call
    VAR_IN_OUT
        result : SMC_NC_GArgument;
    END_VAR
    VAR_INPUT
        pa : POINTER TO SMC_NC_GArgument;
    END_VA
    RVAR_OUTPUT
        eError : SMC_ERROR;
    END_VAR
    VAR
        g : BOOL;
    END_VAR
    
    g := pa[0].argValue.bValue;
    
    result.argType := pa[1].argType;
    
    CASE result.argType OF
    SMC_GVAR_Type.T_BOOL:
        result.argValue.bValue := SEL(g, pa[1].argValue.bValue, pa[2].argValue.bValue);
    
    SMC_GVAR_Type.T_STRING:
        result.argValue.sValue := SEL(g, pa[1].argValue.sValue, pa[2].argValue.sValue);
    
    SMC_GVAR_Type.T_LREAL:
        result.argValue.fValue := SEL(g, pa[1].argValue.fValue, pa[2].argValue.fValue);
    
    ELSE
        eError := SMC_INVALID_PARAMETER;
    END_CASE

Configuration of SMC_ReadNCFile2

An instance of the CNC_Sel function block is created in the GVL_CNCFunctions global variable list.

An array aCNCFunctions of length 1 is initialized with the name and instance of the function block. This array is then linked in the table funTable of type SMC_NC_GFunctionTable.

aCNCFunctions : ARRAY[0..0] OF SMC_NC_GFunction :=
    [(stName:= 'SEL', iFunc:= GVL_CNCFunctions.g_Sel)];

funTable : SMC_NC_GFunctionTable :=
    (numFunctions:= 1,     pFunction:= ADR(aCNCFunctions)) ;

Finally, this table is passed to the SMC_ReadNCFile2 function block:

rncf2 : SMC_ReadNCFile2 := (bParenthesesAsComments:= FALSE);

[...]

rncf2(
    bExecute:= TRUE,
    sFileName:= sFileName,
    pCustomFunTable:= ADR(funTable),
    pvl:= ADR(varList));

Commissioning

  1. Build the application and download it to a controller.

  2. Start the application, switch to the visualization, and press Start. You can use the Longline radio button to set the value of the variable $LONGLINE$ in the G-code to TRUE or FALSE.